﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;

namespace SNSComponent.Utiltiy
{
   

    public static class HttpUtility
    {
        private static HttpWebRequest BuildRequest(Uri uri, Dictionary<string, string> header, string method)
        {
            HttpWebRequest webRequest = null;
           
            webRequest = HttpWebRequest.Create(uri) as HttpWebRequest;
            webRequest.Method = method;
            if (header != null)
            {
                foreach (var item in header)
                {

                    switch (item.Key)
                    {
                        case "Accept":
                            webRequest.Accept = item.Value;
                            break;
                        case "Content-Type":
                            webRequest.ContentType = item.Value;
                            break;
                        default:
                            webRequest.Headers[item.Key] = item.Value;
                            break;
                    }
                }

            }

            return webRequest;
        }

        public static Task<T> Get<T>(Uri uri, Dictionary<string,string> header , Func< HttpWebResponse,T> resultHandler)
        {
            HttpWebRequest webRequest = BuildRequest(uri, header, "GET");

            TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();

            AsyncCallback getResponseCallback = new AsyncCallback((getResponseResult) =>
            {
                try
                {
                    HttpWebResponse httpResponse = httpResponse = webRequest.EndGetResponse(getResponseResult) as HttpWebResponse;
                    tcs.SetResult(resultHandler(httpResponse));

                }
                catch (WebException e)
                {
                    tcs.SetException(e);
                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }

            });

            webRequest.BeginGetResponse(getResponseCallback, null);
           
            return tcs.Task;
        }

        private static int BUFFER_LENGTH = 2048;

        public static Task<T> Post<T>(Uri uri, Stream postStream, Dictionary<string, string> header, Func<HttpWebResponse, T> resultHandler)
        {
            

            HttpWebRequest webRequest = BuildRequest(uri, header, "POST");

            TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();


            AsyncCallback getResponseCallback = new AsyncCallback((getResponseResult) =>
            {
                HttpWebResponse httpResponse = null;
                try
                {
                    httpResponse  = webRequest.EndGetResponse(getResponseResult) as HttpWebResponse;
                    
                    tcs.SetResult(resultHandler(httpResponse));

                }
                catch (Exception ex)
                {
                    tcs.SetException(ex);
                }
                finally
                {
                    if (httpResponse != null)
                    {
                        httpResponse.Close();
                    }
                }

            });

            webRequest.BeginGetRequestStream((getRequestStreamResult) =>
                        {
                            var requestStream = webRequest.EndGetRequestStream(getRequestStreamResult);
                            using (requestStream)
                            {
                                if (postStream != null)
                                {
                                    byte[] buffer = new byte[BUFFER_LENGTH];

                                    int count = 0;
                                    do
                                    {
                                        count = postStream.Read(buffer, 0, BUFFER_LENGTH);
                                        requestStream.Write(buffer, 0, count);
                                    }
                                    while (count == BUFFER_LENGTH);
                                }
                            }


                            webRequest.BeginGetResponse(getResponseCallback, null);
                        }, null);

            return tcs.Task;

        }
    }

   
}
